// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: jhkim

#pragma once

#include <map>
#include <memory>
#include <regex>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>

#include <simdjson.h>

#include "coin2/base/log.h"
#include "coin2/exchange/base/feed/processor.h"
#include "coin2/exchange/base/market/enums.h"

namespace coin2::exchange::binance_base::feed_v1 {
namespace impl {
using namespace std::string_literals;
using coin2::exchange::base::market::ExchangeType;
using coin2::exchange::base::market::MarketType;

class BinanceBaseFeedProcessor : public coin2::exchange::base::feed::FeedParsingProcessor {

  static constexpr auto MAX_PACKET_PAYLOAD_SIZE = 4 * 1024 * 1024; // 4MB buffer
 public:
  BinanceBaseFeedProcessor(
      const std::string& system_name,
      const MarketExchangeApi& mea,
      const coin2::exchange::di::ConstantInjection& ci,
                           const coin2::exchange::feed::RawParserConfig& config,
                           const std::string& recipe)
      : FeedParsingProcessor(system_name, mea, ci, config,
                             "cc/coin2/exchange/binance_base/feed_v1/schema.json"),
        publish_bbo_book_only_(config.publish_bbo_book_only()),
        funding_rate_only_(recipe == "funding_rate_only") {
      if (auto err = parser_.allocate(MAX_PACKET_PAYLOAD_SIZE); err)
      {
        LOG(ERROR) << simdjson::error_message(err);
      }
  }

  void OnTopicRecord(const coin2::exchange::base::executor::TopicRecordPacket& packet) override;

 protected:
  const bool publish_bbo_book_only_;
  const bool funding_rate_only_;
  std::unordered_map<std::string, std::string> nav_native_to_native_;
  simdjson::ondemand::parser parser_;

  struct FeedTopicStat {
    bool snapshot_received = false;
    bool update_received = false;
  };
  std::unordered_map<std::string, FeedTopicStat> topic_stat_;
  // 20230404T00:00:00
  static constexpr int64_t SNAPSHOT_ADDED_TS = 1'680'537'600'000'000'000LL;
};
}  // namespace impl
using impl::BinanceBaseFeedProcessor;
}  // namespace coin2::exchange::binance_base::feed_v1
